package author_service

import (
	"encoding/json"
	"go-gin-example/models"
	"go-gin-example/pkg/gredis"
	"go-gin-example/pkg/logging"
	"go-gin-example/service/cache_service"
)

type Author struct {
	ID         int
	Name       string
	Department string
	Age        int
	Gender     int
	PhoneNo    string

	PageNum  int
	PageSize int
}

func (a *Author) Add() error {
	author := map[string]interface{}{
		"name":       a.Name,
		"department": a.Department,
		"age":        a.Age,
		"gender":     a.Gender,
		"phone_no":   a.PhoneNo,
	}

	if err := models.AddAuthor(author); err != nil {
		return err
	}

	return nil
}

func (a *Author) Edit() error {
	return models.EditAuthor(a.ID, map[string]interface{}{
		"name":       a.Name,
		"department": a.Department,
		"age":        a.Age,
		"gender":     a.Gender,
	})
}

func (a *Author) Get() (*models.Author, error) {
	var cacheAuthor *models.Author

	cache := cache_service.Author{ID: a.ID}
	key := cache.GetAuthorKey()
	if gredis.Exists(key) {
		data, err := gredis.Get(key)
		if err != nil {
			logging.Info(err)
		} else {
			json.Unmarshal(data, &cacheAuthor)
			return cacheAuthor, nil
		}
	}

	article, err := models.GetAuthor(a.ID)
	if err != nil {
		return nil, err
	}

	gredis.Set(key, article, 3600)
	return article, nil
}

func (a *Author) GetAll() ([]*models.Author, error) {
	var (
		authors, cacheAuthors []*models.Author
	)

	cache := cache_service.Author{
		Name:       a.Name,
		Department: a.Department,

		PageNum:  a.PageNum,
		PageSize: a.PageSize,
	}
	key := cache.GetAuthorsKey()
	if gredis.Exists(key) {
		data, err := gredis.Get(key)
		if err != nil {
			logging.Info(err)
		} else {
			json.Unmarshal(data, &cacheAuthors)
			return cacheAuthors, nil
		}
	}

	authors, err := models.GetAuthors(a.PageNum, a.PageSize, a.getMaps())
	if err != nil {
		return nil, err
	}

	gredis.Set(key, authors, 3600)
	return authors, nil
}

func (a *Author) Delete() error {
	return models.DeleteAuthor(a.ID)
}

func (a *Author) ExistByID() (bool, error) {
	return models.ExistAuthorByID(a.ID)
}

func (a *Author) Count() (int64, error) {
	return models.GetAuthorTotal(a.getMaps())
}

func (a *Author) getMaps() map[string]interface{} {
	maps := make(map[string]interface{})
	maps["deleted_on"] = 0
	if a.Name != "" {
		maps["name"] = a.Name
	}

	return maps
}
